import {Converter} from "./hc-dicom-converter.es6";
    
const ZOOM_MAX = 8,
      ZOOM_MIN = 0.1;

export class Canvas {
    constructor(canvas) {
        try {
            this.ctx = canvas.getContext("2d");
        } catch (ex) {
            throw new Error("Not a valid canvas html5 dom node!");
        }

        this.canvas   = canvas;
        this.img      = null;
        this.imgData  = null;

        const w       = canvas.width,
              h       = canvas.height;

        // viewer中心和绝对原点的偏差量        
        this.npi    = Number.parseInt;
        this.diffX  = this.npi(w / 2);
        this.diffY  = this.npi(h / 2);

        this.width  = w;
        this.height = h;

        // img坐标,大小(相对于viewer的中心点)
        this.imgX   = -this.diffX;
        this.imgY   = -this.diffY;
        this.imgW   = w;
        this.imgH   = h;  

        this.zoomRatio = 1;

        // 平移坐标原点到Viewer的中心
        this.ctx.translate(this.diffX, this.diffY);

        // 在内存中运行一个辅助的canvas
        let c               = document.createElement("canvas");
        c.width             = w;
        c.height            = h;
        this.ctxInMemory    = c.getContext("2d");        
        this.canvasInMemory = c;

        // 窗宽 窗位
        this.ww = -1;
        this.wc = -1;
        
        this.converter = null;
    } 

    toImage(format = "jpeg") {
        this.img      = new Image();
        this.img.src  = this.canvas.toDataURL(`image/${format}`);
        return this.img;
    }

    setImage(img) {
        this.img      = img;
        this.imgData  = null;
    }

    setImageData(imgData) {
        this.imgData = imgData;
        this.img = null;

        this.ctxInMemory.putImageData(imgData, 0, 0);
    }

    prepareForAdjustWwWc(pixelBuffer, rescaleSlope = 1, rescaleIntercept = 1024, endian = true) {
        if (!this.converter) {
            this.converter = new Converter(rescaleSlope, rescaleIntercept, endian);
            this.converter.setImageData(this.imgData);
        }
        this.converter.setPixelBuffer(pixelBuffer);
    }
    
    adjustWwWc(wwOffset, wcOffset) {
        this.ww += wwOffset;
        this.wc += wcOffset;        
        this.adjust();
    }
    
    adjustWwWcTo(ww, wc) {
        this.ww = ww;
        this.wc = wc;
        this.adjust();
    }
    
    adjust() {
        this.converter.setWwWc(this.ww, this.wc);
        this.setImageData(this.converter.getImageData());
        this.draw();
    }
    
    transformCoordinate(x, y) {
        x -= this.diffX;
        y -= this.diffY;

        return {x, y};
    }

    translate(offsetX, offsetY) {       
        this.imgX += this.npi(offsetX / this.zoomRatio);
        this.imgY += this.npi(offsetY / this.zoomRatio);

        this.draw();
    }

    translateTo(x, y) {
        let c     = this.transformCoordinate(x, y);
        this.imgX = c.x;
        this.imgY = c.y;

        this.draw();
    }

    zoom(ratio) {
        let r = this.zoomRatio * ratio;
        if (r <= ZOOM_MAX && r >= ZOOM_MIN) {
            this.zoomRatio = r;
            this.draw();
        }
    }

    zoomTo(ratio) {        
        if (ratio <= ZOOM_MAX && ratio >= ZOOM_MIN) {
            this.zoomRatio = ratio;        
            this.draw(); 
        }
    }

    draw() {
        this.ctx.save();
        this.ctx.clearRect(-this.diffX, -this.diffY, this.width, this.height); 
        this.ctx.scale(this.zoomRatio, this.zoomRatio);
        if (this.img) {
            console.log(this.imgX, "  ", this.imgY);
            this.ctx.drawImage(this.img, 0, 0, this.imgW, this.imgH, this.imgX, this.imgY, this.width, this.height); 
        } else if (this.imgData) {
            //this.ctx.putImageData(this.imgData, 0, 0, 0, 0, this.width, this.height); 
            this.ctx.drawImage(this.canvasInMemory, 0, 0, this.imgW, this.imgH, this.imgX, this.imgY, this.width, this.height);
        }
        this.ctx.restore();  
    }
}